今天的內容只建立子彈的類別,和初始化子彈圖片;之後子彈會讓玩家和怪物射擊,程式碼會比之前稍微複雜,因此明天才會講如何讓玩家射擊,子彈被建立渲染在遊戲視窗。
# before
class Mob(pygame.sprite.Sprite):
def __init__(self, construction: dict, **kwargs):
self.image_id = "mob"
self.move_steps = 15
self.used_frame = 0
self.last_move_frame = 0
self.move_cd = 15
"mob"
→ “bullet”
# after
class Bullet(pygame.sprite.Sprite):
def __init__(self, construction: dict, **kwargs):
self.image_id = "bullet"
由於子彈小於玩家和怪物,我們很難傳遞玩家或怪物的某個位置,為子彈左上角的座標,所以我將玩家或怪物的中心點座標傳給子彈
因此子彈需要將中心點的座標,重新導正到 "_init_pos"
這個玩家或怪物的中心點位置
class Bullet(pygame.sprite.Sprite):
def __init__(self, construction: dict, **kwargs):
self.rect.center = construction["_init_pos"]
由於玩家和怪物射擊的方向不同,而我的子彈是有方向性的,因此我增加在初始化時判斷是否為 Mob 的子彈,若是,則將圖片反轉 180度
class Bullet(pygame.sprite.Sprite):
def __init__(self, construction: dict, **kwargs): if self.id == "mob":
if self.id == "mob":
self.angle = 180 * 3.14 // 180
# before
class Bullet(pygame.sprite.Sprite):
def update(self) -> None:
self.used_frame += 1
self.rect.center += self.vel
if self.used_frame - self.last_move_frame > self.move_cd:
if self.move_steps > 10:
self.move_right()
else:
self.move_left()
self.move_steps -= 1
if self.move_steps <= 0:
self.move_steps = 20
self.move_down()
self.last_move_frame = self.used_frame
else:
self.vel = Vec(0, 0)
刪除用不到的 Mob 移動設定,只保留物件中心座標,每回合加上速度
# after
class Bullet(pygame.sprite.Sprite):
def update(self) -> None:
if self.id == "player":
self.move_up()
else:
self.move_down()
在 Bullet 寫上在 Mob 裡沒有的 move_up
行為
# after
class Bullet(pygame.sprite.Sprite):
def move_up(self):
self.vel.y = -self.speed
get_info_to_game_result
物件名稱和 x, y 座標
# before
class Bullet(pygame.sprite.Sprite):
def get_data_from_obj_to_game(self) -> dict:
info = {"id": self.image_id
, "x": self.rect.x
, "y": self.rect.y
}
return info
由於遊戲 A I 需要知道這顆子彈是敵人的,還是玩家的,因此除了 image_id 物件的名字外,用 _
連接 id 代表是誰的子彈
# after
class Bullet(pygame.sprite.Sprite):
def get_data_from_obj_to_game(self) -> dict:
info = {"id": f"{self.image_id}_{self.id}"
, "x": self.rect.x
, "y": self.rect.y
}
return info
關於 mlgame 渲染圖片的資料格式,可以在第 1 0 天的「用程式寫遊戲給AI玩 @MLGameTemplate」裡提到的「MLGame繪製畫面的格式規範請看 GitHub@MLGame/PyGameView.md」找到解答。
# before
class Bullet(pygame.sprite.Sprite):
def get_obj_progress_data(self) -> dict or list:
image_data = create_image_view_data(self.image_id, *self.rect.topleft, self.rect.width, self.rect.height, self.angle)
return image_data
由於子彈的圖片我這裡使用了六張不同顏色的子彈圖片,因此除了 image_id 物件的名字外,用 _
連接 no 代表是第幾張子彈
# after
class Bullet(pygame.sprite.Sprite):
def get_obj_progress_data(self) -> dict or list:
image_data = create_image_view_data(f"{self.image_id}_{self.no}", *self.rect.topleft, *self.get_size(), self.angle)
return image_data
get_init_image_data
函式裡。class BattleMode:
def get_init_image_data(self):
for no in range(1, 7):
init_image_data.append(create_asset_init_data(f"bullet_{no}", *(12, 27)
, path.join(IMAGE_DIR, f"bullet_0{no}.png"), "url"))
# README.md
...
## Image Sours
Mob Image —— @金吉局 繪師
Bullet Image —— @金吉局 繪師
...
今日檔案更新有: